#ifndef SObjectModel_H
#define SObjectModel_H

#include "SObject.h"

///////////////////////////////////////////////////////////////////////////////
class SObjectItem;
typedef QSharedPointer<SObjectItem> SObjectItemPtr;
///////////////////////////////////////////////////////////////////////////////

class SObjectItem
{
public:
	SObjectItem();

	void setObject(const SObjectPtr &v) { m_object = v;}
	SObjectPtr object() const { return m_object;}

	int childCount() const;
	int columnCount() const;
	int childRow() const;

	SObjectItem *parent() const { return m_parentItem;}
	SObjectItem *child(int row) const { return m_childItems[row].data();}

	//bool insertChild(int row,const SObjectItemPtr &insItem);
	void appendChild(const SObjectItemPtr &insItem);
	void appendChild(const QList<SObjectItemPtr> &insItems);
	
	//bool removeChildren(int row,int count);
	void removeChildren();

	QVariant data(int column) const;
	
private:
	SObjectPtr m_object;
	SObjectItem *m_parentItem;
	QList<SObjectItemPtr> m_childItems;
};

///////////////////////////////////////////////////////////////////////////////

class SObjectModel : public QAbstractItemModel
{
	Q_OBJECT

public:
	SObjectModel(QObject *parent);
	~SObjectModel();

	void setRootItem(const SObjectItemPtr &item);

	SObjectItem *rootItem() const { return m_rootItem.data();}
	QModelIndex rootIndex() const { return createIndex(0,0,m_rootItem.data());}
	SObjectItem *itemFromIndex(const QModelIndex &index) const;

public: //QAbstractItemModel
	//bool setHeaderData(int section,Qt::Orientation orientation,const QVariant &value,int role = Qt::EditRole);
	QVariant headerData(int section,Qt::Orientation orientation,int role = Qt::DisplayRole) const;

	QModelIndex index(int row,int column,const QModelIndex &parent = QModelIndex()) const;
	QModelIndex parent(const QModelIndex &index) const;
	Qt::ItemFlags flags(const QModelIndex &index) const;

	int rowCount(const QModelIndex &parent = QModelIndex()) const;
	int columnCount(const QModelIndex &parent = QModelIndex()) const;

	//bool setData(const QModelIndex &index,const QVariant &value,int role = Qt::EditRole);
	QVariant data(const QModelIndex &index,int role) const;

	//bool insertRows(int row,int count,const QModelIndex &parent = QModelIndex());
	//bool removeRows(int row,int count,const QModelIndex &parent = QModelIndex());

	//bool canFetchMore(const QModelIndex &parent) const;
	//void fetchMore(const QModelIndex &parent);
	//bool hasChildren(const QModelIndex &parent = QModelIndex()) const;

public:

	//QModelIndex insertItem(int row,VNavItem *insItem,const QModelIndex &parent = QModelIndex());
	//QModelIndex appendItem(VNavItem *insItem,const QModelIndex &parent = QModelIndex());
	//void removeChildren(const QModelIndex &parent);

private:
	SObjectItemPtr m_rootItem;
};

///////////////////////////////////////////////////////////////////////////////

class SObjectModelLoader : public IBaseVisitor
{
public:
	SObjectModelLoader(const SGroupObjectsGlobalPtr &globalGroup,SObjectModel *model);
/*	
	virtual void startGroupObjects(SObject *p);
	virtual void endGroupObjects(SObject *p);
	virtual void visitObject(SObject *p);
*/
	SObjectItemPtr factoryItem(SObject *p) const;
	
private:
	SGroupObjectsGlobalPtr m_globalGroup;
	SObjectModel *m_model;
	QStack<SObjectItem*> m_parentItems;
};

///////////////////////////////////////////////////////////////////////////////

#endif
